package cn.znzz.cjm.controller;

import cn.znzz.cjm.config.HighlightResultMapper;
import cn.znzz.cjm.doc.CourseDoc;
import cn.znzz.cjm.doc.QueryDoc;
import cn.znzz.cjm.repository.CourseDocReposition;
import cn.znzz.cjm.util.AjaxResult;
import cn.znzz.cjm.util.PageList;
import cn.znzz.cjm.vo.AggVo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/coursedoc")
public class CourseDocController {
    @Autowired
    private CourseDocReposition courseDocReposition;
    @Autowired
    private HighlightResultMapper highlightResultMapper;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @PostMapping("/saveCourseDoc")
    @PreAuthorize("hasAuthority('courseDoc:add')")
    public AjaxResult saveCourseDoc(@RequestBody CourseDoc doc){
        courseDocReposition.save(doc);
        return AjaxResult.me();
    }
    @PostMapping("/delCourseDoc")
    public AjaxResult delCourseDoc(@RequestBody CourseDoc doc){
        courseDocReposition.deleteById(doc.getId());
        return AjaxResult.me();
    }
    @PostMapping("/queryCourses")
    public AjaxResult queryCourses(@RequestBody QueryDoc courseQuery){

        //先创建builder
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //聚合查询,按照机构名字聚合，安装数量倒排
        builder.addAggregation(AggregationBuilders.terms("tenantNameAgg").field("tenantName").order(Terms.Order.count(false)).size(20));
        builder.addAggregation(AggregationBuilders.terms("couseTypeAgg").field("courseTypeName").order(Terms.Order.count(false)).size(20));
        //创建boolquery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //添加匹配的
        String keyword = courseQuery.getKeyword();
        if (!StringUtils.isEmpty(keyword)) {
            boolQuery.must(QueryBuilders.multiMatchQuery(courseQuery.getKeyword(),"name","courseTypeName","gradeName"));
        }
        //添加过滤
        List<QueryBuilder> filter = boolQuery.filter();
        if(courseQuery.getPriceMin()!=null){
            filter.add(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin()));
        }
        if(courseQuery.getPriceMax() != null){
            filter.add(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax()));
        }
        builder.withQuery(boolQuery);
        //添加排序
        //指定排序字段
        String sortField = courseQuery.getSortField();
        //如果前端没有排序的 默认按照价格排序
        sortField=StringUtils.isEmpty(sortField)?"price":sortField;
        FieldSortBuilder sortBuilder = new FieldSortBuilder(sortField);
        //指定排序类型
        String sortType = courseQuery.getSortType();
        SortOrder sortOrder=SortOrder.DESC.toString().equalsIgnoreCase(sortType)?SortOrder.DESC : SortOrder.ASC;
        builder.withSort(sortBuilder.order(sortOrder));
        //分页
        builder.withPageable(PageRequest.of(courseQuery.getPage() - 1, courseQuery.getRows()));
        //在es中进行搜索
        // NativeSearchQuery searchQuery = builder.build();
        // Page<CourseDoc> page = courseRepository.search(searchQuery);
        //指定高亮字段和颜色
        HighlightBuilder.Field field = new HighlightBuilder.Field("name").preTags("<font style='color:red'><b>").postTags("</b></font>");
        builder.withHighlightFields(field);  // 名字高亮
        AggregatedPage<CourseDoc> page = elasticsearchTemplate.queryForPage(builder.build(), CourseDoc.class, highlightResultMapper);
        //聚合
        StringTerms tenantNameAgg = (StringTerms)page.getAggregation("tenantNameAgg");
        ArrayList<AggVo> tlist = new ArrayList<>();
        List<StringTerms.Bucket> buckets = tenantNameAgg.getBuckets();
        for(StringTerms.Bucket buket:buckets){
            AggVo aggVo = new AggVo();
            aggVo.setKey(buket.getKeyAsString());
            aggVo.setCount(buket.getDocCount());
            tlist.add(aggVo);
        }
        StringTerms couseTypeAgg = (StringTerms)page.getAggregation("couseTypeAgg");
        ArrayList<AggVo> clist = new ArrayList<>();
        List<StringTerms.Bucket> cbuckets = couseTypeAgg.getBuckets();
        for(StringTerms.Bucket buket:cbuckets){
            AggVo aggVo = new AggVo();
            aggVo.setKey(buket.getKeyAsString());
            aggVo.setCount(buket.getDocCount());
            clist.add(aggVo);
        }
        HashMap<String, ArrayList<AggVo>> map = new HashMap<>();
        map.put("clist",clist);
        map.put("tlist",tlist);

        //前端要进行分页的话我们就要传递一个pageList
        PageList<CourseDoc> pageList = new PageList<>(page.getTotalElements(),page.getContent(),map);
        return AjaxResult.me().setResultObj(pageList);
    }
}
